/*
 * Copyright (c) 2016, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* TI-Drivers includes                                                        */
#include <ti/drivers/Power.h>
#include <ti/display/Display.h>

/* Application includes                                                       */
#include "wifi_doorlock_app.h"
#include "network_if.h"
#include "cloud_ota_task.h"
#include "provisioning_task.h"
#include "ble_provisioning.h"
#include "platform.h"

extern void Mqtt_stop();
extern void Motor_stop();
extern void Buttons_stop();

extern int32_t StopReconnectTimer(void);
extern int32_t Network_IF_ProcessRestartRequest(void);

extern Application_CB App_CB;
extern Display_Handle display;
extern mqd_t bleQueueSend;

//*****************************************************************************
//
//! \brief This task handles system resets requested by different system
//!        processes
//!
//! \param[in]  None
//!
//! \return None
//!
//****************************************************************************
void * ControlTask(void *pvParameters)
{
    /* System status variables                                                          */
    struct controlMsg controlMsg = {0};

    sem_post(&App_CB.controlReady);
    sem_wait(&App_CB.startBarrier);

    Display_printf(display, 0, 0,"");
    Display_printf(display, 0, 0,"**** Starting control thread loop ****");

    /* Start power use-case                                                              */
#ifdef USE_POWER_POLICY
    Power_enablePolicy();
#endif

    /* Main application loop */
    while (1)
    {
        /* waiting for signals                                                               */
        mq_receive(App_CB.controlQueue, (char*) &controlMsg, sizeof(struct controlMsg), NULL);

        if (controlMsg.msg == CONTROL_MSG_GENERAL_RESET || (controlMsg.threadID == 2 && controlMsg.msg == CONTROL_MSG_OTA_IMAGE_TEST))
        {
            Display_printf(display, 0, 0, "[Control Thread] A thread requested a system reset, %d", controlMsg.threadID);
            Display_printf(display, 0, 0, "[Control Thread] To Complete - Closing all threads and resources");

            /* Stop any running processes for safe reset                                     */
            Motor_stop();
            Mqtt_stop();

            Platform_Reset();

            Display_printf(display, 0, 0, "[Control Thread] ProcessRestartMcu: platform does not support self reset\r\n");
            Display_printf(display, 0, 0, "[Control Thread] ProcessRestartMcu: reset the NWP to rollback to the old image\r\n");

            Network_IF_ProcessRestartRequest();
        }
        else if (controlMsg.threadID == 1 && controlMsg.msg == CONTROL_MSG_OTA_START)
        {
            Display_printf(display, 0, 0, "[Control Thread] Starting OTA...");
            OtaSignalEvent(OTA_EVENT_START);
        }
        else
        {
            Display_printf(display, 0, 0, "[Control Thread] Invalid requester - ignoring request and continuing");
        }
    }
}

